/*
 * IORNN.h
 *
 *  Created on: Dec 17, 2014
 *      Author: Phong
 */

#ifndef CGRNN_H_
#define CGRNN_H_

#include "cblas.h"
#include <vector>
#include <unordered_set>
#include "Param.h"
#include "Matrix.h"
#include "Default.h"
#include "Deptree.h"
#include "Treebank.h"
#include "Corpus.h"
#include <random>
using namespace std;

class CGRNN {
public:
	Dictionary *vocaDic, *posDic, *deprelDic;
	int dim, wdim;
	Param *params;

	discrete_distribution<int> noiseDistr;

	CGRNN(int dim, Dictionary* vocaDic, Dictionary* posDic, Dictionary* deprelDic, vector<Matrix*>& L);
	virtual ~CGRNN();

	void initParam(vector<Matrix*>& L);

	void save(string fname);

	static CGRNN* load(string fname);

	Param* createGrad();

	static Matrix* func(Matrix* X);

	static Matrix* funcPrime(Matrix* F);

	static Matrix* sigmoid(Matrix* X);

	void compForward(Deptree* tree);

	real genForward(Deptree* tree, Matrix* rootOuter);

	void genBackprop(Deptree* tree, Param* grad, real mult = 1);

	void compBackprop(Deptree* tree, Param* grad, Matrix* gradRoot);

	virtual real computeCostAndGrad(Container* data, int startId, int endId, Param** grad, unordered_set<int> &tWords, unordered_set<int> &tPath);

	// make sure gradients are computed correctly
	void checkGradient(Container* tb);

protected:
	CGRNN() {}

};

#endif /* CGRNN_H_ */
